package com.bestcem.xm.deliver.grpc.client;

import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.bestcem.xm.deliver.convert.grpc.DeliverGrpcConvertMapper;
import com.bestcem.xm.deliver.grpc.client.dto.RespondentDto;
import com.bestcem.xm.deliver.grpc.client.dto.SurveyRespondentDto;
import com.bestcem.xm.survey.grpc.v1.services.*;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import zhongyan.xm.base.v1.Base;

import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.bestcem.xm.deliver.enums.RespondentStatusEnum.RESPONDENT_STATUS_NOTSTART;

@Slf4j
@Component
public class SurveyGrpcClient {


    @GrpcClient(GrpcClientNames.DS_SURVEY)
    private BaseSurveyServiceGrpc.BaseSurveyServiceBlockingStub baseStub;

    @GrpcClient(GrpcClientNames.DS_SURVEY)
    private BpSurveyServiceGrpc.BpSurveyServiceBlockingStub stub;

    @GrpcClient(GrpcClientNames.DS_SURVEY)
    private BpSurveyTicketServiceGrpc.BpSurveyTicketServiceBlockingStub bpSurveyTicketServiceBlockingStub;

    private final com.bestcem.xm.deliver.convert.grpc.DeliverGrpcConvertMapper deliverGrpcConvertMapper;

    public SurveyGrpcClient(DeliverGrpcConvertMapper deliverGrpcConvertMapper) {
        this.deliverGrpcConvertMapper = deliverGrpcConvertMapper;
    }

    @Nullable
    public RespondentDto getRespondentBySeq(Long seq, String projectId) {
        GetRespondentBySeqRequest.Builder builder = GetRespondentBySeqRequest.newBuilder();
        if (Objects.nonNull(seq)) {
            builder.setSeq(seq);
        }
        if (ObjectId.isValid(projectId)) {
            builder.setProjectId(projectId);
        }
        try {
            GetRespondentBySeqResponse response = bpSurveyTicketServiceBlockingStub.getRespondentBySeq(builder.build());
            if (Objects.isNull(response) || Base.Code.ERROR.equals(response.getStatus().getCode())) {
                log.error("[deliver] SURVEY getRespondentBySeq Error; {},{}; ErrorMsg: {}", seq, projectId, response);
                return null;
            }
            return deliverGrpcConvertMapper.responseToRespondentDto(response);
        } catch (Exception e) {
            log.error("[deliver] SURVEY getRespondentBySeq Error; {},{}", seq, projectId, e);
            return null;
        }
    }

    public List<SurveyRespondentDto> listRespondent(JSONObject param) {
        ListRespondentRequest.Builder builder = ListRespondentRequest.newBuilder();
        Respondent.Builder respondentbuilder = Respondent.newBuilder();
        if (!StrUtil.isBlankIfStr(param.getString("project_id"))) {
            respondentbuilder.setProjectId(param.getString("project_id"));
        }
        if (!StrUtil.isBlankIfStr(param.getString("status"))) {
            respondentbuilder.setStatus(RespondentStatus.forNumber(param.getInteger("status")));
        }
        if (!StrUtil.isBlankIfStr(param.getString("dlvr_rid"))) {
            respondentbuilder.setDlvrRid(param.getString("dlvr_rid"));
        }
        if (!StrUtil.isBlankIfStr(param.getString("member_id"))) {
            respondentbuilder.setMemberId(param.getString("member_id"));
        }
        if (!StrUtil.isBlankIfStr(param.getString("deliver_id"))) {
            respondentbuilder.setDeliverId(param.getString("deliver_id"));
        }
        if (!StrUtil.isBlankIfStr(param.getString("deliver_group_id"))) {
            respondentbuilder.setDeliverGroupId(param.getString("deliver_group_id"));
        }

        builder.setRespondent(respondentbuilder);
        try {
            RespondentSearchResponse response = baseStub.listRespondent(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[deliver] listRespondent, Error; ErrorMsg: {}", response);
                return Collections.emptyList();
            }
            return deliverGrpcConvertMapper.toSurveyRespondentDtoList(response.getRespondentListList());
        } catch (Exception e) {
            log.error("[deliver] ex listRespondent, Error; ErrorMsg: {}", e.getMessage());
            return Collections.emptyList();
        }
    }


    public List<JSONObject> getDeliverRspdAmountBatch(String deliver_id, List<String> member_id_list, Integer status, String project_id) {
        //rpc GetRespondentAmountBatch(GetRespondentAmountBatchRequest) returns (GetRespondentAmountBatchResponse);
        GetRespondentAmountBatchRequest.Builder builder = GetRespondentAmountBatchRequest.newBuilder();
        if (StrUtil.isNotBlank(deliver_id)) {
            builder.setDeliverId(deliver_id);
        }
        if (StrUtil.isNotBlank(project_id)) {
            builder.setProjectId(project_id);
        }
        if (Objects.nonNull(status)) {
            builder.setStatus(status);
        }
        if (!CollectionUtils.isEmpty(member_id_list)) {
            builder.addAllMemberId(member_id_list);
        }

        try {
            GetRespondentAmountBatchResponse response = baseStub.getRespondentAmountBatch(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[deliver] getDeliverRspdAmountBatch, Error; ErrorMsg: {}", response);
                return Collections.emptyList();
            }
            if (response.getRespondentList().size() == 0) {
                return Collections.emptyList();
            }
            return response.getRespondentList().stream().map(respondent -> {
                JSONObject one = new JSONObject();
                one.put("member_id", respondent.getMemberId());
                one.put("amount", respondent.getCount());
                return one;
            }).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("[deliver] ex getDeliverRspdAmountBatch, Error; ErrorMsg: {}", e.getMessage());
            return Collections.emptyList();
        }
    }


    public List<JSONObject> getDeliverRspdStatusBatch(String deliver_id, List<String> member_id_list, String status, String project_id) {
        //rpc GetRespondentStatusBatch(GetRespondentStatusBatchRequest) returns (GetRespondentStatusBatchResponse);
        log.info("[DELIVER] getDeliverRspdStatusBatch deliver_id={},member_id_list={},status={},project_id={}", deliver_id, JSONArray.toJSONString(member_id_list), status, project_id);
        GetRespondentStatusBatchRequest.Builder builder = GetRespondentStatusBatchRequest.newBuilder();
        if (StrUtil.isNotBlank(deliver_id)) {
            builder.setDeliverId(deliver_id);
        }
        if (StrUtil.isNotBlank(project_id)) {
            builder.setProjectId(project_id);
        }
        if (StrUtil.isNotBlank(status)) {
            builder.setStatus(Integer.parseInt(status));
        }
        if (!CollectionUtils.isEmpty(member_id_list)) {
            builder.addAllMemberId(member_id_list);
        }

        try {
            GetRespondentStatusBatchResponse response = baseStub.getRespondentStatusBatch(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[deliver] getRespondentStatusBatch, Error; ErrorMsg: {}", response);
                return Collections.emptyList();
            }
            if (response.getRespondentList().size() == 0) {
                return Collections.emptyList();
            }
            return response.getRespondentList().stream().map(respondent -> {
                JSONObject one = new JSONObject();
                one.put("status", respondent.getStatus());
                one.put("member_id", respondent.getMemberId());
                return one;
            }).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("[deliver] ex getRespondentStatusBatch, Error; ErrorMsg: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    //rpc GetFinishedAllMemberIds(GetFinishedAllMemberIdsRequest) returns (GetFinishedAllMemberIdsResponse);
    public List<String> getFinishedAllMemberIds(String project_id, Long start_time, Long end_time) {
        log.info("[deliver] getFinishedAllMemberIds project_id={},start_time={},end_time={}", project_id, start_time, end_time);
        if (StrUtil.isBlankIfStr(project_id) || start_time == null || end_time == null) {
            log.error("[deliver] getFinishedAllMemberIds 参数不合法");
            return Collections.emptyList();
        }
        GetFinishedAllMemberIdsRequest.Builder builder = GetFinishedAllMemberIdsRequest.newBuilder();
        builder.setProjectId(project_id);
        builder.setFromTs(start_time);
        builder.setToTs(end_time);

        try {
            GetFinishedAllMemberIdsResponse response = baseStub.getFinishedAllMemberIds(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[deliver] getFinishedAllMemberIds, Error; ErrorMsg: {}", response);
                return Collections.emptyList();
            }
            return response.getMemberIdList();
        } catch (Exception e) {
            log.error("[deliver] ex getFinishedAllMemberIds, Error; ErrorMsg: {}", e.getMessage());
            return Collections.emptyList();
        }

    }

    public Integer getDeliverRspdAmount(String deliverId, String groupId, List<String> groupIdList, String memberId,
                                        Integer status, List<String> dedCodeList, String projectId) {
        // 获取门店投放的成功完成数据
        GetDeliverRspdAmountRequest.Builder builder = GetDeliverRspdAmountRequest.newBuilder();
        if (StringUtils.isNotEmpty(deliverId)) {
            builder.setDeliverId(deliverId);
        }
        if (StringUtils.isNotEmpty(memberId)) {
            builder.setMemberId(memberId);
        }
        if (groupId != null) {
            builder.setGroupId(groupId);
        }

        if (StringUtils.isNotEmpty(memberId)) {
            builder.setMemberId(memberId);
        }
        if (StringUtils.isNotEmpty(projectId)) {
            builder.setProjectId(projectId);
        }
        if (status != null) {
            builder.setStatus(status.toString());
        }
        if (!CollectionUtils.isEmpty(groupIdList)) {
            builder.addAllGroupIdList(groupIdList);
        }
        if (!CollectionUtils.isEmpty(dedCodeList)) {
            builder.addAllDedCodeList(dedCodeList);
        }
        try {
            GetDeliverRspdAmountResponse response = baseStub.getDeliverRspdAmount(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[deliver] getDeliverRspdAmount, Error; ErrorMsg: {}", response);
                return 0;
            }
            return response.getAmount();
        } catch (Exception e) {
            log.error("[deliver] ex getDeliverRspdAmount, Error; ErrorMsg: {}", e.getMessage());
            return 0;
        }
    }

    public Integer getDeliverRspdStatus(String deliverId, String memberId, String dedCode, Integer status, String projectId) {
        // 获取某投放的投放对象的答题状态
        // 获取门店投放的成功完成数据
        GetDeliverRspdStatusRequest.Builder builder = GetDeliverRspdStatusRequest.newBuilder();
        if (StringUtils.isNotEmpty(deliverId)) {
            builder.setDeliverId(deliverId);
        }
        if (StringUtils.isNotEmpty(dedCode)) {
            builder.setDedCode(dedCode);
        }
        if (StringUtils.isNotEmpty(memberId)) {
            builder.setMemberId(memberId);
        }
        if (StringUtils.isNotEmpty(projectId)) {
            builder.setProjectId(projectId);
        }
        if (status != null) {
            builder.setStatus(status.toString());
        }
        try {
            GetDeliverRspdStatusResponse response = baseStub.getDeliverRspdStatus(builder.build());
            if (Objects.isNull(response) || response.getStatus().getCodeValue() != 0) {
                log.error("[deliver] getDeliverRspdStatus, Error; ErrorMsg: {}", response);
                return RESPONDENT_STATUS_NOTSTART.getValue();
            }
            if (StringUtils.isEmpty(response.getState())) {
                return RESPONDENT_STATUS_NOTSTART.getValue();
            }
            return Integer.parseInt(response.getState());
        } catch (Exception e) {
            log.error("[deliver] ex getDeliverRspdStatus, Error; ErrorMsg: {}", e.getMessage());
            return RESPONDENT_STATUS_NOTSTART.getValue();
        }
    }

    //public Integer getDeliverMemberRespTotalCount(String deliver_id, String member_id, String project_id) {
    //    return getDeliverRspdAmount(deliver_id, null, null, member_id,
    //            RESPONDENT_STATUS_FINISH.getValue(), null, project_id);
    //}

    //public Integer getDeliverRespStatus(String deliverId, String memberId, String projectId) {
    //    return getDeliverRspdStatus(deliverId, memberId, null, null, projectId);
    //}
}
